/**
 * @author notifyer
 * @email ls5231@gmail.com
 * @date 2011.8.16
 */

package org.openjava.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class ReflectionUtils{
	
	/**
	 * invoke the method of obj through name,default to the method with no args
	 * @param obj 
	 * @name method name
	 * 
	 */
	public static Object invokeMethodByName(Object obj,String name) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException{
		Class<?> clazz = obj.getClass();
		Method target = clazz.getDeclaredMethod(name);
		if(target == null){
			return null;
		}
		boolean accessible = target.isAccessible();
		target.setAccessible(true);
		Object result = null;
		result = target.invoke(obj);
		target.setAccessible(accessible);
		return result;
	}
	
	/**
	 * invoke the bean's property's getter method
	 * @param bean
	 * @property 
	 */
	public static Object getProperty(Object bean,String property) {
		String getMethod = "get" + StringUtils.capitalize(property);
		try {
			return  invokeMethodByName(bean, getMethod);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * return ture if the obj is json's most minimus element
	 */
	public static boolean isJSONMinObj(Object obj){
		return obj instanceof String 
		|| obj instanceof Number;
	}
	
	/**
	 * return ture if the clazz is json's most minimus class
	 */
	public static boolean isJSONMinClass(Class<?> clazz){
		return clazz.getName().equals("java.lang.String")
		|| clazz.getSuperclass().getName().equals("java.lang.Number");
	}
	/**
	 * return true if the obj's toString method is not inherited from Object
	 */
	public static boolean isToStrMeaningfulObj(Object obj){
		return obj != null && obj.toString().equals(obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode()));
	}
	
	
	/**
	 * invoke the object'method with the  method and the args
	 * @param object
	 * @param method
	 * @param args
	 * @return Object
	 */
	public static Object invokeMethod(Object object,Method method,Object...args){
		boolean accessible = method.isAccessible();
		method.setAccessible(true);
		Object obj = null;
		try {
			obj = method.invoke(object,args);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		method.setAccessible(accessible);
		return obj;
	} 
}
